﻿'/*
' * FAHWatch7  Copyright Marvin Westmaas ( mtm )
' *
' * This program is free software; you can redistribute it and/or
' * modify it under the terms of the GNU General Public License
' * as published by the Free Software Foundation; version 2
' * of the License. See the included file GPLv2.TXT.
' * 
' * This program is distributed in the hope that it will be useful,
' * but WITHOUT ANY WARRANTY; without even the implied warranty of
' * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' * GNU General Public License for more details.
' * 
' * You should have received a copy of the GNU General Public License
' * along with this program; if not, write to the Free Software
' * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
' */
'/*	

Imports System.Xml
Imports System.Text.RegularExpressions
Imports System.Text
Imports Microsoft.Win32
Imports System.IO
Imports System.Runtime.Serialization.Json.DataContractJsonSerializer
Imports System.Runtime.Serialization.Json
Public Class clsClientConfig
    Implements IDisposable
    Public Class clsConfiguration
        Implements IDisposable
        Private _ClientLocation As String, _DataLocation As String
        Private _ConfigDT As DateTime, _strConfigDT As String ' Add conversions!!!
        Private aPath As String = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData)
#Region "Properties"
        Public Property strConfigurationDT As String
            Get
                Return _strConfigDT
            End Get
            Set(value As String)
                _strConfigDT = value
            End Set
        End Property
        Public Property ConfigurationDT As DateTime
            Get
                Return _ConfigDT
            End Get
            Set(value As DateTime)
                _ConfigDT = value
            End Set
        End Property
        Public ReadOnly Property DataLocation As String
            Get
                Return _DataLocation
            End Get
        End Property
        Public ReadOnly Property ClientLocation As String
            Get
                Return _ClientLocation
            End Get
        End Property
#Region "Slots"
        Public Class sSlot
            Implements IEqualityComparer(Of sSlot)
            Public type As String = ""
            Public id As String = ""
            Friend mArguments As New Dictionary(Of String, String)
            Public Sub AddArgument(ByVal Name As String, ByVal Value As String)
                mArguments.Add(Name, Value)
            End Sub
            Public ReadOnly Property NumberOfArguments As Int32
                Get
                    Return mArguments.Count
                End Get
            End Property
            Public Function HasKey(ByVal Key As String) As Boolean
                Return mArguments.ContainsKey(Key)
            End Function
            Public Function ChangeKey(Key As String, Value As String) As Boolean
                mArguments(Key) = Value
                Return True
            End Function
            Public Function GetValue(ByVal Key As String) As String
                If Not HasKey(Key) Then
                    WriteLog("Accessing a slot ket which doesn't excist - " & Key, eSeverity.Important)
                    Return ""
                Else
                    Return mArguments(Key)
                End If
            End Function
            Public Function Keys() As List(Of String)
                Dim lNames As New List(Of String)
                lNames.AddRange(mArguments.Keys)
                Return lNames
            End Function
            Public Function Equals1(x As sSlot, y As sSlot) As Boolean Implements System.Collections.Generic.IEqualityComparer(Of sSlot).Equals
                Dim rVal As Boolean = False
                Try
                    If x.mArguments.Count <> y.mArguments.Count Then Exit Try
                    For xInt As Int32 = 0 To x.Keys.Count - 1
                        If x.mArguments.Keys(xInt) <> y.mArguments.Keys(xInt) Then
                            Exit Try
                        ElseIf x.mArguments.Values(xInt) <> y.mArguments.Values(xInt) Then
                            Exit Try
                        End If
                    Next
                    rVal = True
                Catch ex As Exception
                    WriteError(ex.Message, Err)
                    rVal = False
                End Try
                Return rVal
            End Function
            Public Function GetHashCode1(obj As sSlot) As Integer Implements System.Collections.Generic.IEqualityComparer(Of sSlot).GetHashCode
                Return obj.mArguments.Count
            End Function
        End Class
        Private mslots As New List(Of sSlot)
        Public ReadOnly Property slots As List(Of sSlot)
            Get
                Return mslots
            End Get
        End Property
        Public ReadOnly Property Slot(ID As String) As sSlot
            Get
                For Each Slot In mslots
                    If Slot.id = ID Then Return Slot
                Next
                WriteLog("Accessing a slot which doesn't excist!", eSeverity.Important)
                Return New sSlot
            End Get
        End Property
#End Region
#Region "Extra users"
        Public Class clsExtraUser
            Public slot As String ' id NOT index!
            Public user As String = ""
            Public team As String = ""
            Public passkey As String = ""
        End Class
        Private mXUsers As New List(Of clsExtraUser)
        Public ReadOnly Property ExtraUsers As List(Of clsExtraUser)
            Get
                Dim nXUsers As New List(Of clsExtraUser)
                For Each nUser In mXUsers
                    If nUser.passkey = "" Then nUser.passkey = UserInformation.passkey
                    If nUser.team = "" Then nUser.team = UserInformation.team
                    If nUser.user = "" Then nUser.user = UserInformation.user
                    nXUsers.Add(nUser)
                Next
                Return nXUsers
            End Get
        End Property
        Public ReadOnly Property user(ByVal slot As String) As clsExtraUser ' slot = id NOT index!
            Get
                Dim rUser As New clsExtraUser
                rUser.user = ClientConfig.Configuration.UserInformation.user
                rUser.team = ClientConfig.Configuration.UserInformation.team
                rUser.passkey = ClientConfig.Configuration.UserInformation.passkey
                Try
                    For Each xUser In mXUsers
                        If xUser.slot = slot Then
                            rUser.slot = slot
                            If xUser.user <> "" Then rUser.user = xUser.user
                            If xUser.team <> "" Then rUser.team = xUser.team
                            If xUser.passkey <> "" Then rUser.passkey = xUser.passkey
                            Exit For
                        End If
                    Next
                Catch ex As Exception
                    WriteError(ex.Message, Err)
                End Try
                Return rUser
            End Get
        End Property
#End Region
#Region "Configuration sections"
        Public Class clsConfigSection
            Public Name As String
            Private mArguments As New Dictionary(Of String, String)
            Public Sub AddArgument(ByVal Name As String, ByVal Value As String)
                mArguments.Add(Name, Value)
            End Sub
            Public ReadOnly Property NumberOfArguments As Int32
                Get
                    Return mArguments.Count
                End Get
            End Property
            Public Function HasKey(ByVal Key As String) As Boolean
                Return mArguments.ContainsKey(Key)
            End Function
            Public Function ChangeKey(Key As String, Value As String) As Boolean
                mArguments(Key) = Value
                Return True
            End Function
            Public Function GetValue(ByVal Key As String) As String
                Try
                    If Not HasKey(Key) Then
                        Return ""
                    Else
                        If mArguments(Key).ToUpper.Contains("BETA") Then
                            Return New String(CChar("*"), CInt(mArguments(Key)))
                        Else
                            Return mArguments(Key)
                        End If
                    End If
                Catch ex As Exception
                    WriteError(ex.Message, Err)
                    Return "!VALUE ERROR!"
                End Try
            End Function
            Public Function Keys() As List(Of String)
                Dim lNames As New List(Of String)
                lNames.AddRange(mArguments.Keys)
                Return lNames
            End Function
        End Class
        Private mConfigSection As New List(Of clsConfigSection)
        Public ReadOnly Property ConfigSections As List(Of clsConfigSection)
            Get
                Return mConfigSection
            End Get
        End Property
#End Region
#Region "Remote command server"
        Public Class sRemoteCommandServer
            Public password As String = ""
            Public port As String = "36330"
        End Class
        Public RemoteCommandServer As New sRemoteCommandServer
#End Region
#Region "User information"
        Public Class sUserInformation
            Public passkey As String = ""
            Public user As String = ""
            Public team As String = ""

            Public ReadOnly Property passkeyValid As Boolean
                Get
                    Try
                        If passkey.Length = 32 Then
                            For xInt As Int16 = 0 To 31
                                If Mid(passkey, xInt + 1, 1) <> ("a") And Mid(passkey, xInt + 1, 1) <> ("b") And Mid(passkey, xInt + 1, 1) <> ("c") And Mid(passkey, xInt + 1, 1) <> ("d") And Mid(passkey, xInt + 1, 1) <> ("e") And Mid(passkey, xInt + 1, 1) <> ("f") And Mid(passkey, xInt + 1, 1) <> ("0") And Mid(passkey, xInt + 1, 1) <> ("1") And Mid(passkey, xInt + 1, 1) <> ("2") And Mid(passkey, xInt + 1, 1) <> ("3") And Mid(passkey, xInt + 1, 1) <> ("4") And Mid(passkey, xInt + 1, 1) <> ("5") And Mid(passkey, xInt + 1, 1) <> ("6") And Mid(passkey, xInt + 1, 1) <> ("7") And Mid(passkey, xInt + 1, 1) <> ("8") And Mid(passkey, xInt + 1, 1) <> ("9") Then
                                    Return False
                                End If
                            Next
                            Return True
                        Else
                            Return False
                        End If
                    Catch ex As Exception
                        WriteError(ex.Message, Err)
                        Return False
                    End Try
                End Get
            End Property

        End Class
        Public UserInformation As New sUserInformation
#End Region
        Public ConfigString As String = ""
#End Region
#Region "Functions"
        Public Function SetLocations(Optional ByVal DoLog As Boolean = False) As Boolean
            Try
                Dim rRoot As RegistryKey
                If DoLog Then WriteLog("Openining registry root LOCAL_MACHINE")
                rRoot = Registry.LocalMachine
                If DoLog Then WriteLog("Trying 'Software\Microsoft\Windows\CurrentVersion\Uninstall\FAHClient'")
                Dim rFKey As RegistryKey = rRoot.OpenSubKey("Software\Microsoft\Windows\CurrentVersion\Uninstall\FAHClient")
                If Not IsNothing(rFKey) Then
ReadKey:
                    If DoLog Then WriteLog("Key openend succesfully!")
                    For Each kVName As String In rFKey.GetValueNames
                        If DoLog Then WriteLog("Found '" & kVName & "' value='" & rFKey.GetValue(kVName).ToString & "'")
                        If kVName = "DataDirectory" Then
                            If DoLog Then WriteLog("DataLocation set to " & rFKey.GetValue(kVName).ToString)
                            _DataLocation = rFKey.GetValue(kVName).ToString
                        ElseIf kVName = "DisplayIcon" Then
                            If DoLog Then WriteLog("FAHClient location set to " & rFKey.GetValue(kVName).ToString.Replace("\FAHClient.ico", ""))
                            _ClientLocation = rFKey.GetValue(kVName).ToString.Replace("\FAHClient.ico", "")
                        End If
                    Next
                Else
                    If DoLog Then WriteLog("Opening registry keys in order")
                    If DoLog Then WriteLog(" -> software")
                    rFKey = rRoot.OpenSubKey("SOFTWARE")
                    If Not IsNothing(rFKey) Then
                        If DoLog Then WriteLog(" -> Microsoft")
                        rFKey = rFKey.OpenSubKey("Microsoft")
                        If Not IsNothing(rFKey) Then
                            If DoLog Then WriteLog(" -> Windows")
                            rFKey = rFKey.OpenSubKey("Windows")
                            If Not IsNothing(rFKey) Then
                                If DoLog Then WriteLog(" -> CurrentVersion")
                                rFKey = rFKey.OpenSubKey("CurrentVersion")
                                If Not IsNothing(rFKey) Then
                                    If DoLog Then WriteLog(" -> Uninstall")
                                    rFKey = rFKey.OpenSubKey("Uninstall")
                                    If Not IsNothing(rFKey) Then
                                        If DoLog Then WriteLog(" -> FAHClient")
                                        rFKey = rFKey.OpenSubKey("FAHClient")
                                        If Not IsNothing(rFKey) Then
                                            GoTo ReadKey
                                        End If
                                    End If
                                End If
                            End If
                        End If
                    End If
                End If
                If DataLocation = "" Then
                    If DoLog Then WriteLog("Query application data location")
                    If My.Computer.FileSystem.DirectoryExists(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\FAHClient") AndAlso My.Computer.FileSystem.FileExists(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\FAHClient\config.xml") Then
                        If DoLog Then WriteLog("Directory found in this users application data, config.xml found =" & My.Computer.FileSystem.FileExists(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\FAHClient\Config.xml"))
                        _DataLocation = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData) & "\FAHClient"
                    ElseIf My.Computer.FileSystem.DirectoryExists(Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) & "\FAHClient") Then
                        If DoLog Then WriteLog("Directory found in common application data, config.xml found=" & Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) & "\FAHClient\Config.xml")
                        _DataLocation = Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData) & "\FAHClient"
                    End If
                    If DataLocation = "" And DoLog = True Then WriteLog("All methods exhausted for data location!")
                End If
                If ClientLocation = "" Then
                    If DoLog Then WriteLog("Searching %path% for FAHClient.exe")
                    Dim dirs() As String = Environment.GetEnvironmentVariable("path").ToString.Split(CChar(";"))
                    For Each dStr As String In dirs
                        If My.Computer.FileSystem.FileExists(dStr & "\FAHClient.exe") Then
                            If DoLog Then WriteLog("Found FAHClient.exe, location=" & dStr)
                            _ClientLocation = dStr
                            Exit For
                        End If
                    Next
                    If ClientLocation = "" And DoLog = True Then WriteLog("All methods exhausted for Client location!")
                End If
            Catch ex As Exception
                WriteError(ex.Message, Err)
            End Try
            Return DataLocation <> "" AndAlso ClientLocation <> ""
        End Function
        Public Function ReadJSON(ByVal jsonString As String, Optional DoLog As Boolean = False) As Boolean
            Dim rVal As Boolean = False
            Try
                Dim sReader As New IO.MemoryStream(System.Text.Encoding.UTF8.GetBytes(jsonString))
                Using xmlJR As XmlReader = JsonReaderWriterFactory.CreateJsonReader(sReader, XmlDictionaryReaderQuotas.Max)
                    xmlJR.Read()
                    Do





                    Loop
                End Using
                Return False
            Catch ex As Exception

            End Try
            Return rVal
        End Function
        Public Function ReadString(ByVal TheString As String, Optional ByVal DoLog As Boolean = False) As Boolean
            Try
                'Remove!
                If DoLog Then WriteLog("Reading Configuration string")
                ConfigString = TheString
                Dim strXML As String = TheString
                strXML = strXML.Replace("'", Chr(34))
                Dim strReader As New IO.StringReader(strXML)
                Me.mConfigSection.Clear()
                Me.mslots.Clear()
                Me.mXUsers.Clear()
                Me.RemoteCommandServer = New clsClientConfig.clsConfiguration.sRemoteCommandServer
                Me.UserInformation = New clsClientConfig.clsConfiguration.sUserInformation
                Using xmlR As Xml.XmlReader = XmlReader.Create(strReader)
                    If xmlR.ReadToFollowing("config") Then
                        xmlR.Read()
                        Do
                            If xmlR.NodeType = XmlNodeType.Comment Then
                                Select Case xmlR.Value.ToString.Trim.ToLower
                                    Case "remote command server"
                                        xmlR.Read() ' whitespace 
                                        Do
                                            If xmlR.Read Then
                                                If xmlR.NodeType = XmlNodeType.Element Then
                                                    Select Case xmlR.Name
                                                        Case Is = "password"
                                                            RemoteCommandServer.password = xmlR.Item(0).ToString
                                                        Case Is = "port"
                                                            RemoteCommandServer.port = xmlR.Item(0).ToString
                                                    End Select
                                                Else
                                                    If xmlR.NodeType = XmlNodeType.Comment Then Exit Do
                                                End If
                                            End If
                                        Loop
                                    Case "user information"
                                        xmlR.Read()
                                        Do
                                            If xmlR.Read Then
                                                If xmlR.NodeType = XmlNodeType.Element Then
                                                    Select Case xmlR.Name
                                                        Case Is = "passkey"
                                                            UserInformation.passkey = xmlR.Item(0).ToString
                                                        Case Is = "user"
                                                            UserInformation.user = xmlR.Item(0).ToString
                                                        Case Is = "team"
                                                            UserInformation.team = xmlR.Item(0).ToString
                                                    End Select
                                                Else
                                                    If xmlR.NodeType = XmlNodeType.Comment Then Exit Do
                                                End If
                                            End If
                                        Loop Until xmlR.EOF
                                    Case "folding slots"
                                        If DebugOutput Then WriteDebug("Start slot parse")
                                        Do
                                            If Not xmlR.IsStartElement Then xmlR.Read()
                                            If xmlR.Name = "slot" Then
                                                Dim nSlot As New sSlot
                                                Dim nUser As New clsClientConfig.clsConfiguration.clsExtraUser
                                                nSlot.id = xmlR.Item(0).ToString
                                                nUser.slot = nSlot.id
                                                nSlot.type = xmlR.Item(1).ToString
                                                Dim slotXML As String = xmlR.ReadInnerXml
                                                If DebugOutput Then WriteDebug("Parsed " & nSlot.id & ":" & nSlot.type)
                                                If Not slotXML = "" Then
                                                    If DebugOutput Then WriteDebug("Parsed " & nSlot.id & ":" & nSlot.type & ", parsing " & slotXML)
                                                    Using ixmlR As XmlReader = XmlReader.Create(New StringReader("<slot>" & slotXML.Trim & "</slot>"))
                                                        Do
                                                            If ixmlR.Read Then
                                                                If ixmlR.NodeType = XmlNodeType.Element Then
                                                                    If Not ixmlR.Name = "slot" Then nSlot.AddArgument(ixmlR.Name, ixmlR.Item(0).ToString)
                                                                End If
                                                            Else
                                                                Exit Do
                                                            End If
                                                        Loop Until ixmlR.EOF
                                                    End Using
                                                End If
                                                mslots.Add(nSlot)
                                                If DebugOutput Then WriteDebug("Slot added")
                                            End If
                                        Loop Until xmlR.EOF Or xmlR.NodeType = XmlNodeType.Comment
                                    Case Else
                                        Dim nSection As New clsConfigSection
                                        nSection.Name = xmlR.Value.Trim.ToLower
                                        xmlR.Read()
                                        Do
                                            If xmlR.NodeType = XmlNodeType.Element Then
                                                If xmlR.Name = "slot" Then
                                                    Dim nSlot As New sSlot
                                                    nSlot.type = xmlR.Value
                                                    nSlot.id = CStr(slots.Count + 1)
                                                    If Not slots.Contains(nSlot) Then
                                                        mslots.Add(nSlot)
                                                    Else
                                                        WriteDebug("check")
                                                    End If
                                                End If
                                                Try
                                                    If xmlR.HasAttributes Then nSection.AddArgument(xmlR.Name, xmlR.Item(0).ToString)
                                                    If xmlR.HasValue Then nSection.AddArgument(xmlR.Name, xmlR.Value.ToString)
                                                Catch ex As Exception

                                                End Try
                                            End If
                                            xmlR.Read()
                                        Loop Until xmlR.NodeType = XmlNodeType.Comment Or xmlR.EOF
                                        ConfigSections.Add(nSection)
                                End Select
                            End If
                            If Not xmlR.EOF And Not xmlR.NodeType = XmlNodeType.Comment Then xmlR.Read()
                        Loop While Not xmlR.EOF
                    Else
                        If DoLog Then WriteLog("Could not parse the FAHClient.xml file.")
                        Return False
                    End If
                End Using
                Return True
            Catch ex As Exception
                WriteError(ex.Message, Err)
                Return False
            End Try
        End Function
        Public Function ReadFile(Optional ByVal DoLog As Boolean = False, Optional ByVal FillLocation As Boolean = False) As Boolean
            Try
                If FillLocation Then
                    If Not SetLocations() Then
                        If DoLog Then WriteLog("Can not find config.xml.")
                        Return False
                    End If
                End If
                If DoLog Then WriteLog("Reading Config.xml file.")
                Dim strXML As String = My.Computer.FileSystem.ReadAllText(DataLocation & "\Config.xml")
                ConfigString = strXML
                strXML = strXML.Replace("'", Chr(34))
                Return ReadString(strXML, DoLog)
            Catch ex As Exception
                WriteError(ex.Message, Err)
                Return False
            End Try
        End Function
        Public Function Report(Optional ByVal HideKey As Boolean = False) As String
            Dim sb As New StringBuilder
            Try
                sb.AppendLine("Client config report")
                sb.AppendLine("Remote command server, port: " & RemoteCommandServer.port & " Password length(!): " & RemoteCommandServer.password.Length.ToString)
                sb.AppendLine("User configaration, name: " & UserInformation.user & " Team: " & UserInformation.team & " passkey length: " & UserInformation.passkey.Length.ToString & " valid: " & UserInformation.passkeyValid.ToString)
                sb.AppendLine("Number of folding slots: " & slots.Count)
                For Each singleSlot In slots
                    sb.AppendLine("Slot: " & singleSlot.id & " - " & singleSlot.type)
                    For iInd As Int32 = 0 To singleSlot.NumberOfArguments - 1
                        sb.AppendLine("-" & singleSlot.Keys(iInd) & ": " & singleSlot.GetValue(singleSlot.Keys(iInd)))
                    Next
                Next
                sb.AppendLine("User count: " & 1 + ExtraUsers.Count)
                For Each xUser In ExtraUsers
                    sb.AppendLine("user: " & xUser.user & " team: " & xUser.team & " passkey present(!): " & (xUser.passkey.Length > 0).ToString)
                Next
                sb.AppendLine("Additional configuration sections: " & ConfigSections.Count)
                For Each cSection In ConfigSections
                    sb.AppendLine(cSection.Name)
                    For iInd As Int32 = 0 To cSection.NumberOfArguments - 1
                        If Not cSection.Keys(iInd) = "passkey" Then
                            sb.AppendLine("-" & cSection.Keys(iInd) & ": " & cSection.GetValue(cSection.Keys(iInd)))
                        Else
                            sb.AppendLine("-Passkey present")
                        End If
                    Next
                Next
                sb.AppendLine("")
                sb.AppendLine("Original file:")
                If HideKey Then
                    If ConfigString.Contains("<passkey v='") Then
                        sb.Append(ConfigString.Substring(0, ConfigString.IndexOf("<passkey v='") + Len("<passkey v='")))
                        sb.Append("**hidden**")
                        sb.Append(ConfigString.Substring(ConfigString.IndexOf("/>", ConfigString.IndexOf("<passkey v='"))))
                    End If
                Else
                    sb.Append(ConfigString)
                End If
            Catch ex As Exception
                sb.AppendLine("Exception: " & ex.Message)
                sb.AppendLine("-stacktrace: " & ex.StackTrace)
            End Try
            Return sb.ToString
        End Function
#End Region

#Region "IDisposable Support"
        Private disposedValue As Boolean ' To detect redundant calls

        ' IDisposable
        Protected Overridable Sub Dispose(disposing As Boolean)
            If Not Me.disposedValue Then
                If disposing Then
                    ' TODO: dispose managed state (managed objects).
                End If

                ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
                ' TODO: set large fields to null.
            End If
            Me.disposedValue = True
        End Sub

        ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
        'Protected Overrides Sub Finalize()
        '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        '    Dispose(False)
        '    MyBase.Finalize()
        'End Sub

        ' This code added by Visual Basic to correctly implement the disposable pattern.
        Public Sub Dispose() Implements IDisposable.Dispose
            ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
            Dispose(True)
            GC.SuppressFinalize(Me)
        End Sub
#End Region

    End Class
    Public Configuration As New clsConfiguration

    Public ReadOnly Property Port As String
        Get
            Return Configuration.RemoteCommandServer.port
        End Get
    End Property
    Public ReadOnly Property PWD As String
        Get
            Return Configuration.RemoteCommandServer.password
        End Get
    End Property
    Public ReadOnly Property Team As String
        Get
            Return Configuration.UserInformation.team
        End Get
    End Property
    Public ReadOnly Property User As String
        Get
            Return Configuration.UserInformation.user
        End Get
    End Property
    Public ReadOnly Property PassKey As String
        Get
            Return Configuration.UserInformation.passkey
        End Get
    End Property

    Public Function ReadFAHClientConfig(Optional ByVal DoLog As Boolean = False, Optional ByVal FillLocations As Boolean = False) As Boolean
        Try
            Return Configuration.ReadFile(DoLog, FillLocations)
        Catch ex As Exception
            WriteError(ex.Message, Err)
            Return False
        End Try
    End Function

#Region "IDisposable Support"
    Private disposedValue As Boolean ' To detect redundant calls

    ' IDisposable
    Protected Overridable Sub Dispose(disposing As Boolean)
        If Not Me.disposedValue Then
            If disposing Then
                ' TODO: dispose managed state (managed objects).
                Configuration.Dispose()
            End If

            ' TODO: free unmanaged resources (unmanaged objects) and override Finalize() below.
            ' TODO: set large fields to null.
        End If
        Me.disposedValue = True
    End Sub

    ' TODO: override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
    'Protected Overrides Sub Finalize()
    '    ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    ' This code added by Visual Basic to correctly implement the disposable pattern.
    Public Sub Dispose() Implements IDisposable.Dispose
        ' Do not change this code.  Put cleanup code in Dispose(ByVal disposing As Boolean) above.
        Dispose(True)
        GC.SuppressFinalize(Me)
    End Sub
#End Region

End Class

